﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Sockets;
using Modbus;
using 工业设备监控系统.BLL;
using 工业设备监控系统.Models;
using Modbus.Device;
using 工业设备监控系统.Interface;

namespace 工业设备监控系统.configure
{
    public partial class ModbusFrm : Form
    {
        private IModbusSerialMaster master;
        private int value = 0;
        private ModbusTcpConnection modbusTcpConnection;
        public int registerAddress { get; set; }

        public enum StoreArea
        {
            输出线圈0x,
            输入状态1x,
            输出寄存器4x,
            输入寄存器3x
        }

        public enum VarType
        {
            Bit,
            Short,
            UShort,
            Int,
            UInt,
            Float
        }

        //创建连接标志位
        private bool IsConnected = false;

        //创建通信对象
        private ModbusRtu objmodbusRtu = new ModbusRtu();

        //系统当前时间
        private string CurrentTime
        {
            get { return DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); }
        }

        private TestDataBLL TestDataBLL = new TestDataBLL();

        public ModbusFrm()
        {
            InitializeComponent();
            //端口号
            string[] PortList = SerialPort.GetPortNames();

            if (PortList.Length > 0)
            {
                this.cb_Port.Items.AddRange(PortList);
                this.cb_Port.SelectedIndex = 0;
            }

            //波特率
            this.cb_BaudRate.DataSource = new string[] { "2400", "4800", "9600", "19200", "38400" };
            this.cb_BaudRate.SelectedIndex = 2;

            //校验位
            this.cb_CheckSit.DataSource = Enum.GetNames(typeof(Parity));

            //停止位
            this.cb_StopSit.DataSource = Enum.GetNames(typeof(StopBits));
            this.cb_StopSit.SelectedIndex = 1;

            this.cb_dataStyle.DataSource = Enum.GetNames(typeof(DataFormat));
        }

        private void Modbus_Load(object sender, EventArgs e)
        {
            //端口号
            string[] PortList = SerialPort.GetPortNames();

            if (PortList.Length > 0)
            {
                this.cb_Port.Items.AddRange(PortList);
                this.cb_Port.SelectedIndex = 0;
            }

            //波特率
            this.cb_BaudRate.DataSource = new string[] { "2400", "4800", "9600", "19200", "38400" };
            this.cb_BaudRate.SelectedIndex = 2;

            //校验位
            this.cb_CheckSit.DataSource = Enum.GetNames(typeof(Parity));

            //停止位
            this.cb_StopSit.DataSource = Enum.GetNames(typeof(StopBits));
            this.cb_StopSit.SelectedIndex = 1;

            //数据格式
            this.cb_dataStyle.DataSource = Enum.GetNames(typeof(DataFormat));

            //存储区
            this.cb_SaveSit.DataSource = Enum.GetNames(typeof(StoreArea));

            //数据类型
            this.cb_VarityNumberStyle.DataSource = Enum.GetNames(typeof(VarType));
            //串口通信对象实例化
        }

        private void btn_CreateLink_Click(object sender, EventArgs e)
        {
            //判断是否连接
            if (IsConnected)
            {
                MessageBox.Show("ModbusRTU已连接，请勿重复连接!");
                return;
            }
            try
            {
                master = objmodbusRtu.OpenMyCom(int.Parse(this.cb_BaudRate.Text.Trim()), this.cb_Port.Text.Trim(), int.Parse(this.txt_datasit.Text.Trim()), (Parity)Enum.Parse(typeof(Parity), this.cb_CheckSit.SelectedItem.ToString(), false), (StopBits)Enum.Parse(typeof(StopBits), this.cb_StopSit.SelectedItem.ToString(), false));
            }
            catch (Exception ex)
            {
                IsConnected = false;
                MessageBox.Show("ModbusRTU已连接，请勿重复连接!");
                return;
            }
            IsConnected = true;

            MessageBox.Show("ModbusRTU已连接!");
        }

        private async void btn_Read_Click(object sender, EventArgs e)
        {
            if (!IsConnected)
            {
                return;
            }
            //  txt_Variable.Text = registerAddress.ToString();
            ushort DevAdd = 0;
            ushort Address = 0;
            ushort Length = 0;
            if (!ushort.TryParse(this.txt_SlaveAdd.Text.Trim(), out DevAdd))
            {
                MessageBox.Show("读取失败，从站地址必须为正整数");
                return;
            }
            if (!ushort.TryParse(this.txt_Variable.Text.Trim(), out Address))
            {
                MessageBox.Show("读取失败，起始地址必须为正整数");
                return;
            }
            if (!ushort.TryParse(this.txt_Length.Text.Trim(), out Length))
            {
                MessageBox.Show("读取失败，读取长度必须为正整数");
                return;
            }

            //获取选择的变量类型
            VarType varType = (VarType)Enum.Parse(typeof(VarType), this.cb_VarityNumberStyle.SelectedItem.ToString(), false);
            //获取选择的存储区
            StoreArea storeArea = (StoreArea)Enum.Parse(typeof(StoreArea), this.cb_SaveSit.SelectedItem.ToString(), false);

            //创建字节数组
            byte[] result = null;
            //数据读取
            switch (varType)
            {
                case VarType.Bit:
                    switch (storeArea)
                    {
                        case StoreArea.输出线圈0x:
                            result = objmodbusRtu.ReadOutputStatus(DevAdd, Address, Length);
                            break;

                        case StoreArea.输入状态1x:
                            result = objmodbusRtu.ReadInputStatus(DevAdd, Address, Length);

                            break;

                        case StoreArea.输出寄存器4x:
                        case StoreArea.输入寄存器3x:
                            MessageBox.Show("读取失败,存储区类型不正确!");
                            return;
                    }
                    string binarystring = string.Empty;
                    if (result != null)
                    {
                        foreach (var item in result)
                        {
                            char[] c = Convert.ToString(item, 2).PadLeft(8, '0').ToCharArray();
                            Array.Reverse(c);
                            binarystring += new string(c);
                        }
                        MessageBox.Show("读取成功，结果为:" + binarystring.Substring(0, Length));
                        value = int.Parse(binarystring.Substring(0, Length));
                    }
                    else
                    {
                        MessageBox.Show("读取失败,请检查地址、类型、或者连接状态");
                    }
                    break;

                case VarType.Short:
                    switch (storeArea)
                    {
                        case StoreArea.输出线圈0x:
                        case StoreArea.输入状态1x:
                            MessageBox.Show("读取失败,存储区类型不正确!");
                            break;

                        case StoreArea.输出寄存器4x:
                            result = objmodbusRtu.ReadKeepReg(DevAdd, Address, Length);
                            break;

                        case StoreArea.输入寄存器3x:
                            break;

                        default:
                            break;
                    }
                    string shortString = string.Empty;
                    if (result != null && result.Length == Length * 2)
                    {
                        for (int i = 0; i < result.Length; i += 2)
                        {
                            shortString += BitConverter.ToInt16(Get16ByteArray(result, i, objmodbusRtu.DataFormat), 0).ToString() + "";
                        }
                        MessageBox.Show("读取成功，结果为:" + shortString.Trim());
                        value = int.Parse(shortString.Trim());
                    }
                    else
                    {
                        MessageBox.Show("读取失败,请检查地址、类型、或者连接状态");
                    }
                    break;

                case VarType.UShort:
                    switch (storeArea)
                    {
                        case StoreArea.输出线圈0x:
                        case StoreArea.输入状态1x:
                            MessageBox.Show("读取失败,存储区类型不正确!");
                            break;

                        case StoreArea.输出寄存器4x:
                            result = objmodbusRtu.ReadKeepReg(DevAdd, Address, Length);
                            break;

                        case StoreArea.输入寄存器3x:
                            break;

                        default:
                            break;
                    }
                    string UshortString = string.Empty;
                    if (result != null && result.Length == Length * 2)
                    {
                        for (int i = 0; i < result.Length; i += 2)
                        {
                            UshortString += BitConverter.ToUInt16(Get16ByteArray(result, i, objmodbusRtu.DataFormat), 0).ToString() + "";
                        }
                        MessageBox.Show("读取成功，结果为:" + UshortString.Trim());
                        value = int.Parse(UshortString.Trim());
                    }
                    else
                    {
                        MessageBox.Show("读取失败,请检查地址、类型、或者连接状态");
                    }
                    break;

                case VarType.Int:
                    break;

                case VarType.UInt:
                    break;

                case VarType.Float:
                    break;

                default:
                    break;
            }
        }

        public int MainFrm_GetRegisterValue(int address)
        {
            //master = objmodbusRtu.OpenMyCom(int.Parse(this.cb_BaudRate.Text.Trim()), this.cb_Port.Text.Trim(), int.Parse(this.txt_datasit.Text.Trim()), (Parity)Enum.Parse(typeof(Parity), this.cb_CheckSit.SelectedItem.ToString(), false), (StopBits)Enum.Parse(typeof(StopBits), this.cb_StopSit.SelectedItem.ToString(), false));

            //创建字节数组
            byte[] result = null;
            result = objmodbusRtu.ReadKeepReg(1, address, 1);
            string UshortString = string.Empty;
            if (result != null && result.Length == 1 * 2)
            {
                for (int i = 0; i < result.Length; i += 2)
                {
                    UshortString += BitConverter.ToUInt16(Get16ByteArray(result, i, objmodbusRtu.DataFormat), 0).ToString() + "";
                }
                value = int.Parse(UshortString.Trim());
            }
            else
            {
                value = -1;
            }
            //objmodbusRtu.CloseMyCom();
            return value;
        }

        #region 各种类型的数组截取

        private byte[] Get16ByteArray(byte[] byteArray, int start, DataFormat type)
        {
            byte[] Res = new byte[2];
            if (byteArray != null && byteArray.Length >= start + 2)
            {
                byte[] ResTemp = new byte[2];
                for (int i = 0; i < 2; i++)
                {
                    ResTemp[i] = byteArray[start + i];
                }
                switch (type)
                {
                    case DataFormat.ABCD:
                    case DataFormat.CDAB:
                        Res[0] = ResTemp[1];
                        Res[1] = ResTemp[0];
                        break;

                    case DataFormat.BADC:
                    case DataFormat.DCBA:
                        Res = ResTemp;
                        break;
                }
                return Res;
            }
            else
            {
                return null;
            }
        }

        #endregion 各种类型的数组截取

        public int GetValue()
        {
            return value;
        }

        private void btn_breakLink_Click(object sender, EventArgs e)
        {
            objmodbusRtu.CloseMyCom();
            IsConnected = false;
        }

        private void btn_TCPLink_Click(object sender, EventArgs e)
        {
            modbusTcpConnection = new ModbusTcpConnection(ServerIp_txt.Text, int.Parse(ServerPort_txt.Text));
            //  modbusTcpConnection.Connect();
        }

        public ModbusTcpConnection GetModbusTcp()
        {
            return modbusTcpConnection;
        }

        private void btn_disconnect_Click(object sender, EventArgs e)
        {
            modbusTcpConnection.Disconnect();
        }
    }
}